import { App, Provide, Inject, Config, Init } from '@midwayjs/decorator'
import { Application } from 'egg'
import { HttpService } from '@midwayjs/axios'
import { customAlphabet } from 'nanoid'

import { UserService } from './user'
import { decrypt } from '../utils/helper'

type Jscode2sessionResponse = {
  data: {
    session_key: string,
    openid: string
  }
}

@Provide()
export class WechatService {

  protected nanoid: () => string

  @App()
  app: Application

  @Inject()
  httpService: HttpService

  @Inject()
  userService: UserService

  @Config('wechat')
  wxConfig: any

  @Init()
  async init() {
    this.nanoid = customAlphabet('abcdefghABCDEFGH', 8)
  }

  async getUserInfo({ code, encryptedData, iv }) {
    const {
      data: {
        session_key,
        openid
      }
    }: Jscode2sessionResponse = await this.httpService.get('https://api.weixin.qq.com/sns/jscode2session', {
      params: {
        ...this.wxConfig,
        grant_type: 'authorization_code',
        js_code: code
      }
    })

    if (openid) {
      const existedUser = await this.userService.get({ openid })

      if (existedUser) {
        return existedUser
      }

      const {
        avatarUrl,
        nickName
      } = decrypt({
        session_key,
        encryptedData,
        iv
      }, this.wxConfig.appid)

      const addedUser = await this.userService.add({
        openid,
        user_type: 1,
        nickname: nickName,
        avatar: avatarUrl,
        username: 'wx_' + this.nanoid()
      })

      return addedUser
    }
  }
}
